﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Diagnostics;
using Microsoft.Win32;
using System.Windows.Forms;
using System.Threading;

namespace WindowAPI
{
    public class ApiHelper
    {
        #region 定义WindowsAPI接口
        /// <summary>
        /// 模拟键盘事件
        /// </summary>
        /// <param name="bVk"></param>
        /// <param name="bScan"></param>
        /// <param name="dwFlags"></param>
        /// <param name="dwExtraInfo"></param>
        [DllImport("User32.dll")]
        private static extern void keybd_event(Byte bVk, Byte bScan, Int32 dwFlags, Int32 dwExtraInfo);
        /// <summary>
        /// 模拟鼠标事件
        /// </summary>
        /// <param name="dwFlags"></param>
        /// <param name="dx"></param>
        /// <param name="dy"></param>
        /// <param name="cButtons"></param>
        /// <param name="dwExtraInfo"></param>
        /// <returns></returns>
        [DllImport("User32.dll")]
        private static extern int mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
        [DllImport("gdi32.dll")]
        public static extern uint GetPixel(IntPtr hDC, int XPos, int YPos);
        [DllImport("user32.dll")]
        public static extern uint ScreenToClient(IntPtr hwnd, ref Point p_Point);
        [DllImport("user32.dll")]
        public static extern bool GetCursorPos(ref Point p_Point);
        [DllImport("user32.dll")]
        public static extern IntPtr WindowFromPoint(uint x_point, uint y_point);
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr GetDC(IntPtr hWnd);


        [DllImport("GDI32.dll")]
        public static extern bool BitBlt(int hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, int hdcSrc, int nXSrc, int nYSrc, int dwRop);
        [DllImport("GDI32.dll")]
        public static extern int CreateCompatibleBitmap(int hdc, int nWidth, int nHeight);
        [DllImport("GDI32.dll")]
        public static extern int CreateCompatibleDC(int hdc);
        [DllImport("GDI32.dll")]
        public static extern bool DeleteDC(int hdc);
        [DllImport("GDI32.dll")]
        public static extern bool DeleteObject(int hObject);
        [DllImport("GDI32.dll")]
        public static extern int GetDeviceCaps(int hdc, int nIndex);
        [DllImport("GDI32.dll")]
        public static extern int SelectObject(int hdc, int hgdiobj);
        [DllImport("User32.dll")]
        public static extern int GetDesktopWindow();
        [DllImport("User32.dll")]
        public static extern int GetWindowDC(int hWnd);
        [DllImport("User32.dll")]
        public static extern int ReleaseDC(int hWnd, int hDC);



        #endregion

        #region 配置一些静态常量
        private const int MOUSEEVENTF_MOVE = 0x1;//      移动鼠标 
        private const int MOUSEEVENTF_LEFTDOWN = 0x2;// 模拟鼠标左键按下 
        private const int MOUSEEVENTF_LEFTUP = 0x4;// 模拟鼠标左键抬起 
        private const int MOUSEEVENTF_RIGHTDOWN = 0x8;// 模拟鼠标右键按下 
        private const int MOUSEEVENTF_RIGHTUP = 0x10;// 模拟鼠标右键抬起 
        private const int MOUSEEVENTF_ABSOLUTE = 0x8000; //标示是否采用绝对坐标
        private const int MOUSEEVENTF_WHEEL = 0x800; //滚轮滚动
        private static int width = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width;
        private static int height = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height;
        #endregion

        public static void Cleanup(int bitmap, int source, int destination)
        {
            ReleaseDC(GetDesktopWindow(), source); DeleteDC(destination); DeleteObject(bitmap);
        }

        public static System.Drawing.Bitmap GetImage(int hBitmap)
        {
            System.Drawing.Bitmap image = new System.Drawing.Bitmap(System.Drawing.Image.FromHbitmap(new IntPtr(hBitmap)), System.Drawing.Image.FromHbitmap(new IntPtr(hBitmap)).Width, System.Drawing.Image.FromHbitmap(new IntPtr(hBitmap)).Height);
            return image;
        }

        public static System.Drawing.Bitmap GetScreenMap()
        {
            int source = WindowAPI.ApiHelper.GetWindowDC(WindowAPI.ApiHelper.GetDesktopWindow());
            // Secures the image using CreateCompatibleBitmap        
            int bitmap = WindowAPI.ApiHelper.CreateCompatibleBitmap(source, WindowAPI.ApiHelper.GetDeviceCaps(source, 8), WindowAPI.ApiHelper.GetDeviceCaps(source, 10));
            int destination = WindowAPI.ApiHelper.CreateCompatibleDC(source);
            WindowAPI.ApiHelper.SelectObject(destination, bitmap);
            WindowAPI.ApiHelper.BitBlt(destination, 0, 0, WindowAPI.ApiHelper.GetDeviceCaps(source, 8), WindowAPI.ApiHelper.GetDeviceCaps(source, 10), source, 0, 0, 0x00CC0020);
            System.Drawing.Bitmap image = WindowAPI.ApiHelper.GetImage(bitmap);
            WindowAPI.ApiHelper.Cleanup(bitmap, source, destination);
            //  image.Save("e:/d.bmp");
            return image;
        }

        /// <summary>
        /// 单击键盘某个键
        /// </summary>
        /// <param name="key"></param>
        public static void KeyBoardClick(Keys key)
        {
            byte key_value = (byte)key;
            keybd_event(key_value, 0, 0, 0);//按下键盘
            keybd_event(key_value, 0, 2, 0); //松开键盘
        }
        /// <summary>
        /// 单击键盘组合键
        /// </summary>
        /// <param name="key"></param>
        public static void KeyBoardGroup(Keys keyFirst, Keys keySecond)
        {
            byte key1_value = (byte)keyFirst;
            byte key2_value = (byte)keySecond;

            keybd_event(key1_value, 0, 0, 0);//按下键盘
            keybd_event(key2_value, 0, 0, 0);//按下键盘
            keybd_event(key2_value, 0, 2, 0); //松开键盘
            keybd_event(key1_value, 0, 2, 0); //松开键盘
        }
        /// <summary>
        /// 按住键盘某个键
        /// </summary>
        /// <param name="key"></param>
        /// <param name="seconds"></param>
        public static void KeyBoardHode(Keys key, int seconds)
        {
            byte key_value = (byte)key;
            keybd_event(key_value, 0, 0, 0);//按下键盘
            System.Threading.Thread.Sleep(seconds * 1000);
            keybd_event(key_value, 0, 2, 0); //松开键盘
        }

        /// <summary>
        /// 鼠标左键单击
        /// </summary>
        public static void MouseClick(int x, int y)
        {
            mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, x * 65536 / width, y * 65536 / height, 0, 0);
            mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
        }

        /// <summary>
        /// 鼠标右键单击
        /// </summary>
        public static void MouseRightClick(int x, int y)
        {
            mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, x * 65536 / width, y * 65536 / height, 0, 0);
            mouse_event(MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0);
        }
        /// <summary>
        /// 鼠标左键双击
        /// </summary>
        public static void MouseDoubleClick(int x, int y)
        {
            mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, x * 65536 / width, y * 65536 / height, 0, 0);
            mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
            mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
        }

        public static void MouseWheel(int distance)
        {
            mouse_event(MOUSEEVENTF_WHEEL, 0, 0, distance, 0);
        }
        public static void MouseMove(int distance)
        {
            mouse_event(MOUSEEVENTF_MOVE, 0, 0, distance, 0);

        }
        /// <summary>
        /// 得到屏幕上面某个点的颜色
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        public static System.Drawing.Color GetColor(int x, int y)
        {
            Point _Point = new Point();
            _Point.x = x;
            _Point.y = y;
            //  GetCursorPos(ref _Point);
            IntPtr _Hwnd = WindowFromPoint((uint)_Point.x, (uint)_Point.y);
            IntPtr _DC = GetDC(_Hwnd);
            ScreenToClient(_Hwnd, ref _Point);
            uint _ColorLong = GetPixel(_DC, _Point.x, _Point.y);
            System.Drawing.Color _Color = System.Drawing.Color.FromArgb((int)_ColorLong & 0xFF, (int)(_ColorLong & 0xFF00) / 256, (int)(_ColorLong & 0xFF0000) / 65536);
            ReleaseDC(_Hwnd, _DC);
            return _Color;
        }
    }
}
